#include "ConfigImport.h"
#include "ColorfulLog.h"

// #include <mutex>
#include <algorithm>

#if 0
/*懒汉*/
//初始化静态成员变量
ConfigImport *ConfigImport::m_SingleInstance = nullptr;
std::mutex ConfigImport::m_Mutex;
/**********************************
 * 函数名：GetInstance
 * 功能：获取配置对象单一实例
 * 输入：无
 * 输出：无
 * 备注：无
**********************************/
ConfigImport* ConfigImport::getInstance(std::string yaml_loadFile)
{
    //  双检锁，只有判断指针为空的时候才加锁，避免每次调用 GetInstance的方法都加锁
    if (m_SingleInstance == nullptr) 
    {
        std::unique_lock<std::mutex> lock(m_Mutex); // 加锁
        if (m_SingleInstance == nullptr)
        {
            volatile auto temp = new (std::nothrow) ConfigImport(yaml_loadFile);
            m_SingleInstance = temp;
        }
    }
    return m_SingleInstance;
}

void ConfigImport::deleteInstance()
{
    std::unique_lock<std::mutex> lock(m_Mutex); // 加锁
    if (m_SingleInstance)
    {
        delete m_SingleInstance;
        m_SingleInstance = nullptr;
    }
}

#else
/*饿汉*/
//类外初始化：直接创建出类的实例 
ConfigImport* ConfigImport::m_SingleInstance = new ConfigImport("../yaml/loadFile.yaml");
/**********************************
 * 函数名：GetInstance
 * 功能：获取配置对象单一实例
 * 输入：无
 * 输出：无
 * 备注：无
**********************************/
ConfigImport* ConfigImport::getInstance()
{
    if(m_SingleInstance == nullptr){
        printf_red("ConfigImport Instance is not exist!\n");
        exit(1);
    }
    return m_SingleInstance;
}

void ConfigImport::deleteInstance()
{
    if (m_SingleInstance)
    {
        delete m_SingleInstance;
        m_SingleInstance = nullptr;
    }
}
#endif

ConfigImport::ConfigImport(std::string yaml_loadFile):
    pointPerTrial(m_pointPerTrial),
    channalNum(m_channalNum),
    ntPercent(networkShows_SparsePercent)
{
    cacheConfig_reg = 0;
    // pointPerTrial = &pointPerTrial;

    // 配置文件加载
    // std::string yaml_loadFile ("../yaml/loadFile.yaml");
    // 通过配置文件改变文件来源
    std::ifstream configFile(yaml_loadFile,std::ios::in);
    std::string line;
    // 有效性判断
    if(!configFile.is_open()){
        LOG_ERR("file \"%s\" is not exit, open failed.\n",yaml_loadFile.c_str());
        // return -1;
    }

    configMap["dataFileName"] = "defaultData.bin";              // 数据文件
    configMap["testFileName"] = "defaultData.bin";              // 模型预测文件
    
    configMap["labelFileName"] = "defaultData.bin";              // 标签文件
    configMap["test_labelFileName"] = "defaultData.bin";              // 标签文件
    
    configMap["MatrixShape"] = "0x0x0";                     // 数据的维度
    configMap["testMatrixShape"] = "0x0x0";                     // 测试数据的维度
    configMap["dataType"] = data_double;                    // 数据类型
    configMap["EmotionFilterPara"] = "EmotionFilterSet.txt";       // 情绪识别滤波器参数文件

    configMap["GL_Cache"] = "1";       // 全局缓存开关标志
    configMap["CL_Cache"] = "0";       // 全局缓存使能刷新标志
    configMap["simulation_enable"] = "1";       // 全局缓存使能刷新标志

    configMap["filter_cache"] = "0";
    configMap["filter_refresh"] = "0";

    configMap["cor_cache"] = "1";
    configMap["cor_refresh"] = "0";

    configMap["Cache_path"] = "";
    configMap["SVM_modelPath"] = "";

    configMap["pointPerTrial"] = "5000";
    configMap["channalNum"] = "64";
    configMap["NetworkShows_SparsePercent"] = "2.0";

    while (getline(configFile,line)){
        std::istringstream iss(line);
        std::string key,val,eq;
        // 解析配置文件

        // 去除行首尾的空白字符
        line.erase(0,line.find_first_not_of(" \t\n\r\f\v"));
        line.erase(line.find_last_not_of(" \t\n\r\f\v") + 1);
        // 跳过注释行
        if(!line.empty() && line[0] == '#'){
            continue;
        }

        // 获取key
        if(!getline(iss,key,'=')){
            continue;
        }
        // 获取val
        if(!getline(iss,val)){
            continue;
        }
        // 删除key,val两端的空白字符,key.erase(position)方法会删除下标从position往后的所有
        key.erase(key.find_last_not_of(" \t\n\r\f\v") + 1);
        val.erase(0,val.find_first_not_of(" \t\n\r\f\v"));

        // 配置文件录入map  
        if(configMap.find(key) == configMap.end() ){
            printf("Extra parameter in config file, ignored.\n");
        }
        else{
            configMap[key] = val;
        }
    }
    configFile.close();

    size_t pos = 0;
    std::string str = configMap["MatrixShape"];
    while ((pos = str.find('x')) != std::string::npos){
        // 通过x分割出数字,然后压入维度向量中,保存矩阵的维数
        dim.push_back(std::stoi(str.substr(0,pos)));
        // 删除已经读出的字符和分割符
        str.erase(0, pos + 1);
    }
    // 还剩最后一个数字
    dim.push_back(std::stoi(str));

    pos = 0;
    str = configMap["testMatrixShape"];
    while ((pos = str.find('x')) != std::string::npos){
        // 通过x分割出数字,然后压入维度向量中,保存矩阵的维数
        test_dim.push_back(std::stoi(str.substr(0,pos)));
        // 删除已经读出的字符和分割符
        str.erase(0, pos + 1);
    }
    // 还剩最后一个数字
    test_dim.push_back(std::stoi(str));
    
    // #define PRINTF_CONFIG
    #ifdef PRINTF_CONFIG
    printf("dataFileName:%s\n",configMap["dataFileName"].c_str());
    printf("testFileName:%s\n",configMap["testFileName"].c_str());
    printf("MatrixShape:%s\n",configMap["MatrixShape"].c_str());
    // for(int num:dim){
    //     std::cout << num << std::endl;
    // }
    for(int num=0; num<3; ++num){
        std::cout << "dim" << num+1 << ":" << dim[num] << "; ";
    }
    std::cout << std::endl;
    #endif
    // end of 配置文件加载

    // 获取滤波器参数，这里直接用matlab生成，然后读txt，后续看情况更改为C++的数字滤波器
    // getEmotionFiltParaFromMatlab();
    // end of 滤波器参数加载

    // 缓存机制配置
    GL_Cache = std::stoi(configMap["GL_Cache"]);
    CL_Cache = std::stoi(configMap["CL_Cache"]);

    simulation_enable = std::stoi(configMap["simulation_enable"]);
    m_pointPerTrial = std::stoi(configMap["pointPerTrial"]);
    

    if(std::stoi(configMap["filter_cache"]) == 1){
        cacheConfig_reg |= FILTER_CACHE;
    }
    if(std::stoi(configMap["filter_refresh"]) == 1){
        cacheConfig_reg |= FILTER_REFRESH;
    }
    if(std::stoi(configMap["cor_cache"]) == 1){
        cacheConfig_reg |= COR_CACHE;
    }
    if(std::stoi(configMap["cor_refresh"]) == 1){
        cacheConfig_reg |= COR_REFRESH;
    }
    // end of 缓存机制配置

    // 脑电通道数
    m_channalNum = std::stoi(configMap["channalNum"]);
    // end of 脑电通道数

    // 网络显示系数百分比:默认2.0%
    networkShows_SparsePercent = std::stod(configMap["NetworkShows_SparsePercent"]);

}

ConfigImport::~ConfigImport()
{

}

std::string ConfigImport::getMapVal(std::string key){
    std::string res("");
    if(configMap.find(key) == configMap.end()){
        std::cerr << "Error: there is no key named: " << key << " in map." << std::endl;
        return res;
    }
    res = configMap[key];
    return res;
}

bool ConfigImport::get_GL_Cache() const {return GL_Cache;}
bool ConfigImport::get_CL_Cache() const {return CL_Cache;}
bool ConfigImport::use_simulationDev() const {return simulation_enable;}
// int ConfigImport::getpointPerTrial() const {return pointPerTrial;}
bool ConfigImport::is_filter_cache_enable() const 
{
    if((cacheConfig_reg & FILTER_CACHE) == FILTER_CACHE){
        return true;
    }
    else{
        return false;
    }
}
bool ConfigImport::is_filter_cache_refresh() const 
{
    if((cacheConfig_reg & FILTER_REFRESH) == FILTER_REFRESH){
        return true;
    }
    else{
        return false;
    }
}
bool ConfigImport::is_cor_cache_enable() const 
{
    if((cacheConfig_reg & COR_CACHE) == COR_CACHE){
        return true;
    }
    else{
        return false;
    }
}
bool ConfigImport::is_cor_cache_refresh() const 
{
    if((cacheConfig_reg & COR_REFRESH) == COR_REFRESH){
        return true;
    }
    else{
        return false;
    }
}

